/*
 * Copyright (C) 2017-2021
 * All rights reserved, Designed By
 * Copyright authorization contact 18814114118
 */
package com.shop.cereshop.app.service.shop.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.shop.cereshop.app.dao.shop.CereShopCommentDAO;
import com.shop.cereshop.app.page.comment.*;
import com.shop.cereshop.app.page.product.BroadCastDTO;
import com.shop.cereshop.app.page.product.BuyerComment;
import com.shop.cereshop.app.param.comment.*;
import com.shop.cereshop.app.service.buyer.CereBuyerCommentLikeService;
import com.shop.cereshop.app.service.shop.CereShopCommentService;
import com.shop.cereshop.commons.constant.IntegerEnum;
import com.shop.cereshop.commons.domain.buyer.CereBuyerUser;
import com.shop.cereshop.commons.domain.common.Page;
import com.shop.cereshop.commons.domain.shop.CereShopComment;
import com.shop.cereshop.commons.domain.word.CerePlatformWord;
import com.shop.cereshop.commons.exception.CoBusinessException;
import com.shop.cereshop.commons.result.Result;
import com.shop.cereshop.commons.utils.EmptyUtils;
import com.shop.cereshop.commons.utils.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static jdk.nashorn.internal.runtime.regexp.joni.Config.log;

@Slf4j
@Service
public class CereShopCommentServiceImpl implements CereShopCommentService {

    @Autowired
    private CereShopCommentDAO cereShopCommentDAO;

    @Autowired
    private CereBuyerCommentLikeService cereBuyerCommentLikeService;

    @Override
    public List<BuyerComment> findByProductId(Long productId) {
        return cereShopCommentDAO.findByProductId(productId);
    }

    @Override
    public CereShopComment findShop(Long productId) {
        return cereShopCommentDAO.findShop(productId);
    }

    @Override
    public void insert(CereShopComment cereShopComment) throws CoBusinessException {
        cereShopCommentDAO.insert(cereShopComment);
    }

    @Override
    public CommentCount getAll(CommentParam param, CereBuyerUser user) throws CoBusinessException {
        CommentCount commentCount = new CommentCount();
        //查询全部评价数量
        commentCount.setTotal(cereShopCommentDAO.findTotal(user.getBuyerUserId(), null));
        //查询有图评价数量
        commentCount.setImageTotal(cereShopCommentDAO.findTotal(user.getBuyerUserId(), IntegerEnum.YES.getCode()));
        param.setBuyerUserId(user.getBuyerUserId());
        PageHelper.startPage(param.getPage(), param.getPageSize());
        List<SelfComment> list = cereShopCommentDAO.getAll(param);
        if (!EmptyUtils.isEmpty(list)) {
            list.forEach(selfComment -> {
                if (!EmptyUtils.isEmpty(selfComment.getAddTime())) {
                    selfComment.setIfAdd(IntegerEnum.YES.getCode());
                } else {
                    selfComment.setIfAdd(IntegerEnum.NO.getCode());
                }
                //设置规格属性值数组
                selfComment.setValues(EmptyUtils.getImages(selfComment.getValue()));
            });
        }
        PageInfo<SelfComment> pageInfo = new PageInfo<>(list);
        Page page = new Page(pageInfo.getList(), pageInfo.getTotal());
        commentCount.setPage(page);
        return commentCount;
    }

    @Override
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {CoBusinessException.class, Exception.class})
    public void like(LikeParam param, CereBuyerUser user) throws CoBusinessException {
        cereBuyerCommentLikeService.insertOrUpdate(user.getBuyerUserId(), param.getCommentId(), param.getIfLike());
    }

    @Override
    public void update(CereShopComment cereShopComment) throws CoBusinessException {
        cereShopCommentDAO.updateById(cereShopComment);
    }

    @Override
    public CereShopComment findByOrderId(Long orderId) {
        return cereShopCommentDAO.findByOrderId(orderId);
    }

    @Override
    public List<CerePlatformWord> findWords() {
        return cereShopCommentDAO.findWords();
    }


    @Override
    public Page getProductAll(CommentWorParam param) throws CoBusinessException, Exception {
        PageHelper.startPage(param.getPage(), param.getPageSize());
        List<WordComment> list = cereShopCommentDAO.getProductAll(param);
        if (!EmptyUtils.isEmpty(list)) {
            for (WordComment wordComment : list) {
                // 计算追评时间和评价时间之间天数
                if (!EmptyUtils.isEmpty(wordComment.getAddTime())) {
                    wordComment
                            .setDay(TimeUtils.differentDaysByMillisecond(wordComment.getCreateTime(), wordComment.getAddTime()));
                }
                // 设置图片数组
                if (!EmptyUtils.isEmpty(wordComment.getImage())) {
                    wordComment.setImages(EmptyUtils.getImages(wordComment.getImage()));
                }
                if (!EmptyUtils.isEmpty(wordComment.getAddImage())) {
                    wordComment.setAddImages(EmptyUtils.getImages(wordComment.getAddImage()));
                }
            }
        }
        PageInfo<WordComment> pageInfo = new PageInfo<>(list);
        Page page = new Page(pageInfo.getList(), pageInfo.getTotal());
        return page;
    }

    @Override
    public int findProductNumber(Long orderId) {
        return cereShopCommentDAO.findProductNumber(orderId);
    }

    @Override
    public void updateBuyerData(Long buyerUserId, Long id) throws CoBusinessException {
        cereShopCommentDAO.updateBuyerData(buyerUserId, id);
    }

    @Override
    public CereShopComment findComment(Long buyerUserId, Long orderId, Long skuId) {
        return cereShopCommentDAO.findComment(buyerUserId, orderId, skuId);
    }

    @Override
    public CommentCount getCommentList(CommentParam param, CereBuyerUser user) {
        CommentCount commentCount = new CommentCount();
        param.setBuyerUserId(user.getBuyerUserId());
        PageHelper.startPage(param.getPage(), param.getPageSize());
        List<SelfComment> list = null;
        if (param.getType() == 1) {
            list = cereShopCommentDAO.getUnCommentList(param);
        } else {
            list = cereShopCommentDAO.getCommentList(param);
            if (!EmptyUtils.isEmpty(list)) {
                list.forEach(selfComment -> {
                    if (!EmptyUtils.isEmpty(selfComment.getAddTime())) {
                        selfComment.setIfAdd(IntegerEnum.YES.getCode());
                    } else {
                        selfComment.setIfAdd(IntegerEnum.NO.getCode());
                    }
                    // 设置规格属性值数组
                    selfComment.setValues(EmptyUtils.getImages(selfComment.getValue()));
                });
            }
        }
        PageInfo<SelfComment> pageInfo = new PageInfo<>(list);
        Page page = new Page(pageInfo.getList(), pageInfo.getTotal());
        commentCount.setPage(page);
        return commentCount;
    }

    @Override
    public int findCommentCount(Long buyerUserId) {
        return cereShopCommentDAO
                .selectCount(Wrappers.<CereShopComment>lambdaQuery().eq(CereShopComment::getBuyerUserId, buyerUserId));
    }

    @Override
    public List<BroadCastDTO> findRecentComment(Long productId, String oneHourAgo) {
        return cereShopCommentDAO.findRecentComment(productId, oneHourAgo);
    }

    @Override
    public CommentCount getProductCommentFilter(Long productId) {
        return cereShopCommentDAO.getProductCommentCount(productId);
    }

    @Override
    public Page<BuyerComment> getProductComments(CommentWordDTO param, CereBuyerUser user) {
        PageHelper.startPage(param.getPage(), param.getPageSize());
        List<BuyerComment> list = cereShopCommentDAO.getProductComments(param.getProductId(), param.getFilter(), user.getBuyerUserId());
        if (!EmptyUtils.isEmpty(list)) {
            for (BuyerComment buyerComment : list) {
                //处理匿名评价
                if (buyerComment.getBuyerUserId() == null || buyerComment.getBuyerUserId() == 0) {
                    buyerComment.setName("匿名用户");
                    buyerComment.setHeadImage("https://c-ssl.duitang.com/uploads/item/201705/07/20170507160645_23nWC.jpeg");
                }
                // 设置图片数组
                if (!EmptyUtils.isEmpty(buyerComment.getImage())) {
                    buyerComment.setImages(EmptyUtils.getImages(buyerComment.getImage()));
                }
                if (!EmptyUtils.isEmpty(buyerComment.getAddImage())) {
                    buyerComment.setAddImages(EmptyUtils.getImages(buyerComment.getAddImage()));
                }
                //设置发布时间的时间戳
                long time = DateUtil.parse(buyerComment.getCreateTime()).getTime();
                buyerComment.setPublishTime(time);
            }
        }
        PageInfo<BuyerComment> pageInfo = new PageInfo<>(list);
        Page page = new Page(pageInfo.getList(), pageInfo.getTotal());
        return page;
    }

    @Override
    public Result<CommentCount> getProductCommentStatistics(Long productId) {
        CommentCount commentCount = cereShopCommentDAO.getProductCommentCount(productId);
        return Result.success(commentCount);
    }

    @Override
    public PageInfo<ProductCommentVO> getProductCommentList(CommentWordDTO param, Long buyerUserId) {
        PageHelper.startPage(param.getPage(), param.getPageSize());
        QueryProductCommentDTO queryDTO = new QueryProductCommentDTO();
        queryDTO.setProductId(param.getProductId());
        queryDTO.setFilter(param.getFilter());
        queryDTO.setBuyerUserId(buyerUserId);
        List<ProductCommentVO> parentComments = cereShopCommentDAO.getProductCommentList(queryDTO);
        if (CollUtil.isEmpty(parentComments)) {
            log.info("没有评论数据");
            return new PageInfo<>();
        }

        for (ProductCommentVO commentVO : parentComments) {
            //处理匿名评价
            if (commentVO.getBuyerUserId() == null || commentVO.getBuyerUserId() == 0) {
                commentVO.setPublisherName("匿名用户");
                commentVO.setHeadImage("https://c-ssl.duitang.com/uploads/item/201705/07/20170507160645_23nWC.jpeg");
            }
            // 设置图片数组
            if (!EmptyUtils.isEmpty(commentVO.getImage())) {
                commentVO.setImages(EmptyUtils.getImages(commentVO.getImage()));
            }
        }

        // 提取主评论ID列表
        List<Long> parentIds = parentComments.stream().map(ProductCommentVO::getCommentId).collect(Collectors.toList());

        // 批量获取所有回复评论
        List<ProductCommentVO> replyComments = cereShopCommentDAO.getRepliesByParentIds(parentIds, buyerUserId);

        // 构建回复评论的映射关系
        Map<Long, List<ProductCommentVO>> replyMap = replyComments.stream().collect(Collectors.groupingBy(ProductCommentVO::getParentId));

        // 将回复评论关联到主评论
        parentComments.forEach(comment -> {
            List<ProductCommentVO> replies = replyMap.getOrDefault(comment.getCommentId(), new ArrayList<>());
            comment.setReplies(replies);
        });

        return new PageInfo<>(parentComments);
    }

    @Override
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {CoBusinessException.class, Exception.class})
    public void addComment(CommentAddDTO param, CereBuyerUser user) throws CoBusinessException {
        String now = TimeUtils.yyMMddHHmmss();
        if (cereShopCommentDAO.selectCount(new LambdaQueryWrapper<CereShopComment>()
                .eq(CereShopComment::getBuyerUserId, user.getBuyerUserId())
                .eq(CereShopComment::getParentId, param.getCommentId())
                .eq(CereShopComment::getComment, param.getComment())) > 0) {
            throw new CoBusinessException("您已评价过此商品");
        }
        CereShopComment comment = cereShopCommentDAO.selectOne(new LambdaQueryWrapper<CereShopComment>().eq(CereShopComment::getCommentId, param.getCommentId()));
        if (comment == null) {
            throw new CoBusinessException("父级评论不存在");
        }
        CereShopComment newComment = new CereShopComment();
        newComment.setShopId(comment.getShopId())
                .setShopName(comment.getShopName())
                .setShopCode(comment.getShopCode())
                .setProductId(comment.getProductId())
                .setSkuId(comment.getSkuId())
                .setOrderId(comment.getOrderId())
                .setBuyerUserId(user.getBuyerUserId())
                .setComment(param.getComment())
                .setState(0)
                .setParentId(param.getCommentId())
                .setCreateTime(now)
                .setUpdateTime(now)
                .setViewCount(0);
        if (cereShopCommentDAO.insert(newComment) <= 0) {
            throw new CoBusinessException("添加评论失败,请重新添加");
        }
    }

    @Override
    public ShopCommentVO getById(Long commentId, Long buyerUserId) throws CoBusinessException {
        //查询商品一级评论详情
        ShopCommentVO comment = cereShopCommentDAO.getById(commentId, buyerUserId);
        //处理匿名评价
        if (comment.getBuyerUserId() == null || comment.getBuyerUserId() == 0) {
            comment.setName("匿名用户");
            comment.setHeadImage("https://c-ssl.duitang.com/uploads/item/201705/07/20170507160645_23nWC.jpeg");
        }
        //查询商品二级评论列表
        List<ReplyCommentVO> replyComments = cereShopCommentDAO.getReplyComments(commentId);
        //设置图片数组
        if (comment != null && !EmptyUtils.isEmpty(comment.getImage())) {
            comment.setImages(EmptyUtils.getImages(comment.getImage()));
        }
        //字符串时间转换为时间戳
        if (comment != null && replyComments != null) {
            long publishTime = DateUtil.parse(comment.getCreateTime(), "yyyy-MM-dd HH:mm:ss").getTime();
            comment.setPublishTime(publishTime);
            for (ReplyCommentVO replyComment : replyComments) {
                long replyTime = DateUtil.parse(replyComment.getTime(), "yyyy-MM-dd HH:mm:ss").getTime();
                replyComment.setReplyTime(replyTime);
            }
            comment.setReplyComments(replyComments);
        }
        //增加浏览量
        cereShopCommentDAO.addViewCount(commentId);

        return comment;
    }
}


